package com.wzcl.app.service.impl;

import com.wzcl.app.dao.model.AppUser;
import com.wzcl.app.dao.model.Feedback;
import com.wzcl.app.dao.repository.FeedbackRepository;
import com.wzcl.app.model.common.BusinessException;
import com.wzcl.app.model.common.CodeMsg;
import com.wzcl.app.model.common.MyPage;
import com.wzcl.app.model.common.WZCL;
import com.wzcl.app.model.dto.FeedbackDto;
import com.wzcl.app.service.FeedbackService;
import com.wzcl.app.service.UserService;
import com.wzcl.app.utils.CollectionUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@Log4j2
@Service
public class FeedbackServiceImpl implements FeedbackService {

    @Autowired
    private FeedbackRepository repository;

    @Autowired
    private UserService userService;

    @Override
    public Feedback addFeedback(FeedbackDto feedbackDto) {
        Feedback feedback = new Feedback();
        feedback.setContent(feedbackDto.getContent());
        AppUser user = userService.getAndCheckByPhone(feedbackDto.getProvider());
        feedback.setProvider(user.getPhone());
        feedback.setType(feedbackDto.getType());
        feedback.setSchedule(WZCL.SCHEDULE.SUBMIT);
        //设置问题图片与联系方式
        feedback.setImg(feedbackDto.getImg());
        feedback.setImg(feedbackDto.getLink());
        return repository.save(feedback);
    }

    @Override
    public Feedback processFeedback(FeedbackDto feedbackDto) {
        //校验获取
        Feedback feedback = getAndCheckById(feedbackDto);
        //处理反馈(用户提交的，处理中的才可继续处理)
        if (!(WZCL.SCHEDULE.SUBMIT.equals(feedback.getSchedule()) || WZCL.SCHEDULE.PROCESSING.equals(feedback.getSchedule()))) {
            throw new BusinessException(CodeMsg.FEEDBACK_OPERATE_FAIL, "无法处理改反馈");
        }
        feedback.setProgram(feedbackDto.getProgram());
        AppUser user = userService.getAndCheckByPhone(feedbackDto.getProcessor());
        feedback.setProcessor(user.getPhone());
        feedback.setSchedule(StringUtils.isBlank(feedback.getProgram()) ? WZCL.SCHEDULE.PROCESSING : WZCL.SCHEDULE.BE_CONFIRM);
        return repository.save(feedback);
    }

    @Override
    public Feedback commentFeedback(FeedbackDto feedbackDto) {
        if (StringUtils.isBlank(feedbackDto.getSatisfaction())) {
            throw new BusinessException(CodeMsg.MUST_BE_NOT_NULL, "缺少满意度");
        }
        //校验获取
        Feedback feedback = getAndCheckById(feedbackDto);
        //修改
        feedback.setProgram(feedbackDto.getProgram());
        feedback.setProcessor(feedbackDto.getProcessor());
        feedback.setSchedule(WZCL.SCHEDULE.END);
        return repository.save(feedback);
    }

    @Override
    public Feedback getFeedbackById(Integer id) {
        return repository.findById(id).orElse(null);
    }

    @Override
    public Feedback getAndCheckById(Integer id) {
        if (id == null) {
            throw new BusinessException(CodeMsg.MUST_BE_NOT_NULL, "缺少反馈ID");
        }
        Feedback feedback = getFeedbackById(id);
        if (feedback == null) {
            throw new BusinessException(CodeMsg.FEEDBACK_NOT_EXIST);
        }
        return feedback;
    }

    @Override
    public List<Feedback> getFeedbackList(FeedbackDto feedbackDto) {
        return repository.findAll(getSpecification(feedbackDto), feedbackDto.getSort());
    }

    @Override
    public MyPage<Feedback> getFeedbackPage(FeedbackDto feedbackDto) {
        List<Feedback> all = repository.findAll(getSpecification(feedbackDto));
        ArrayList<Feedback> list = new ArrayList<>(all);
        List<Feedback> listBySort = CollectionUtil.getListBySort(list, "getCreateTime", "desc");
        List<Feedback> listByPage = CollectionUtil.getListByPage(listBySort, feedbackDto.getPageNumber(), feedbackDto.getPageSize());
        MyPage<Feedback> myPage = new MyPage<>();
        myPage.setPageSize(feedbackDto.getPageSize());
        myPage.setPageNumber(feedbackDto.getPageNumber());
        myPage.setContent(listByPage);
        myPage.setTotalElements(list.size());
        return myPage;
    }

    private Specification<Feedback> getSpecification(FeedbackDto feedbackDto) {
        return new Specification<Feedback>() {
            @Override
            public Predicate toPredicate(Root<Feedback> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                if (StringUtils.isNotBlank(feedbackDto.getProcessor())) {
                    predicates.add(criteriaBuilder.equal(root.get("processor"), feedbackDto.getProcessor()));
                }
                if (StringUtils.isNotBlank(feedbackDto.getProvider())) {
                    predicates.add(criteriaBuilder.equal(root.get("provider"), feedbackDto.getProvider()));
                }
                if (feedbackDto.getType() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("type"), feedbackDto.getType()));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }
}
